home *** CD-ROM | disk | FTP | other *** search
- static char sccs_id[] = "@(#) alloc.c 5.0 "__DATE__" HJR";
-
- /* alloc.c (c) Copyright 1990 H.Rogers */
-
- /* features multiple free lists hashed on block size */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifdef M_DEBUG
- #include <stdio.h>
- #include <signal.h>
-
- static int __m_fail(char *exp,char *file,int line)
- {
- fprintf(stderr,"\n\"%s\", line %d: Assertion failed: %s\n",file,line,exp);
- raise(SIGABRT);
- return(0);
- }
-
- #define assert(x) (void)((x) ? 0 : __m_fail(#x,__FILE__,__LINE__))
-
- #define addr(x) ((x) ? (*((int *)(x)) | 1) : 0)
-
- #define MAGIC 0x4349474d
- #endif
-
- extern void *sbrk(int);
-
- typedef struct _blk
- {
- #ifdef M_DEBUG
- int magic;
- #endif
- struct _blk *next;
- size_t size;
- } blk;
-
- #ifdef M_DEBUG
- #define BLKSIZ 16 /* smallest power of 2 >= sizeof(blk) */
- #else
- #define BLKSIZ 8
- #endif
-
- #define blkalign(x) (((x) + (BLKSIZ<<1) - 1) & (~(BLKSIZ - 1)))
-
- #define NFL 8
-
- static blk __fl[NFL];
- static size_t __flmin[NFL] =
- {
- 4096 + BLKSIZ,
- 1024 + BLKSIZ,
- 256 + BLKSIZ,
- 64 + BLKSIZ,
- 32 + BLKSIZ,
- 16 + BLKSIZ,
- 8 + BLKSIZ,
- 0 + BLKSIZ /* catchall */
- };
-
- #define MEMINC 12 /* sbrk() memory block bit alignment */
-
- void __allocinit(void)
- {
- register blk *b;
- register int i;
-
- #ifdef M_DEBUG
- assert(sizeof(struct _blk) <= BLKSIZ);
- #endif
-
- for (i = 0; i < NFL; i++)
- {
- b = __fl + i;
- b->next = b;
- b->size = BLKSIZ;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- }
- }
-
- static blk *findblk(register int i,register blk *a)
- {
- register blk *b,*p;
-
- p = __fl + i;
- b = p->next;
-
- #ifdef M_DEBUG
- assert(addr(p));
- assert(p->magic == MAGIC);
- #endif
-
- while (b > p)
- {
- #ifdef M_DEBUG
- assert(addr(b));
- assert(b->magic == MAGIC);
- #endif
- if (b >= a) break;
- p = b;
- b = b->next;
- }
-
- return(p);
- }
-
- #define addblk(i,n,p) ((n)->next = (p)->next,(p)->next = (n))
-
- #define delblk(i,b,p) ((p)->next = (b)->next)
-
- static void concatblk(register blk *a,register blk *p)
- {
- register blk *b;
-
- if (!p) return;
-
- b = p->next;
-
- while ((char *)a + a->size == (char *)b)
- {
- a->size += b->size;
- #ifdef M_DEBUG
- b->magic = 0;
- #endif
- b = b->next;
- }
-
- p->next = b;
- }
-
- static int flindex(register int size)
- {
- register int i;
-
- for (i = 0; size < __flmin[i]; i++);
-
- return(i);
- }
-
- static blk *findsize(register int i,register int size,register blk **p_)
- {
- register blk *b,*p;
-
- p = __fl + i;
- b = p->next;
-
- while (b > p)
- {
- if (b->size >= size)
- { delblk(i,b,p); break; }
- p = b;
- b = b->next;
- }
-
- if (p_) *p_ = p; return(b);
- }
-
- void *malloc(register size_t size)
- {
- register blk *b;
- register int i;
- blk *p;
-
- if (!size) return(0);
-
- size = blkalign(size);
-
- i = flindex(size);
-
- b = findsize(i,size,&p);
-
- if (b <= p)
- {
- register void *m;
- register int _size;
-
- _size = ((size>>MEMINC) + 1)<<MEMINC;
- if ((m = sbrk(_size)) == (void *)-1) return(0);
-
- if ((char *)p + p->size == (char *)m)
- {
- b = p;
- p = findblk(i,b);
- delblk(i,b,p);
- b->size += _size;
- }
- else
- {
- b = (blk *)m;
- b->size = _size;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- }
- }
-
- #ifdef M_DEBUG
- assert(addr(b));
- assert(b->magic == MAGIC);
- #endif
-
- if (b->size > (size + __flmin[i]))
- {
- register blk *n;
-
- n = (blk *)((char *)b + size);
-
- addblk(i,n,p);
-
- n->size = b->size - size;
- #ifdef M_DEBUG
- n->magic = MAGIC;
- #endif
- b->size = size;
- }
-
- return((void *)((char *)b + BLKSIZ));
- }
-
- void *realloc(register void *_a,register size_t size)
- {
- register blk *a;
- register int i;
- blk *p;
-
- if (!(_a)) return(malloc(size));
-
- if (!size) { free(_a); return(0); }
-
- size = blkalign(size);
-
- #ifdef M_DEBUG
- assert(addr(_a));
- #endif
-
- a = (blk *)((char *)_a - BLKSIZ);
-
- #ifdef M_DEBUG
- assert(addr(a));
- assert(a->magic == MAGIC);
- #endif
-
- i = flindex(a->size);
-
- p = findblk(i,a);
-
- concatblk(a,p);
-
- if (a->size < size)
- {
- if ((char *)p + p->size == (char *)a && p->size + a->size >= size)
- {
- register blk *b;
-
- #ifdef M_DEBUG
- assert(addr(p));
- assert(p->magic == MAGIC);
- #endif
- b = p;
- p = findblk(i,b);
- delblk(i,b,p);
- b->size += a->size;
- #ifdef M_DEBUG
- a->magic = 0;
- #endif
- memmove((char *)b + BLKSIZ,_a,a->size - BLKSIZ);
- _a = (char *)(a = b) + BLKSIZ;
- }
- else
- {
- register void *m;
- register int _size;
-
- _size = ((size>>MEMINC) + 1)<<MEMINC;
- if ((m = sbrk(_size)) == (void *)-1) return(0);
-
- if ((char *)a + a->size == (char *)m)
- a->size += _size;
- else
- {
- register blk *b;
-
- addblk(i,a,p);
- b = (blk *)m;
- b->size = _size;
- #ifdef M_DEBUG
- b->magic = MAGIC;
- #endif
- memcpy((char *)b + BLKSIZ,_a,a->size - BLKSIZ);
- _a = (char *)(a = b) + BLKSIZ;
- }
- }
- }
-
- i = flindex(size);
-
- if (a->size > (size + __flmin[i]))
- {
- register blk *n;
-
- p = findblk(i,a);
-
- n = (blk *)((char *)a + size);
-
- addblk(i,n,p);
-
- n->size = a->size - size;
- #ifdef M_DEBUG
- n->magic = MAGIC;
- #endif
- a->size = size;
- }
-
- return(_a);
- }
-
- void free(register void *_a)
- {
- register blk *a,*p;
- register int i;
-
- if (!_a) return;
-
- #ifdef M_DEBUG
- assert(addr(_a));
- #endif
-
- a = (blk *)((char *)_a - BLKSIZ);
-
- #ifdef M_DEBUG
- assert(addr(a));
- assert(a->magic == MAGIC);
- #endif
-
- i = flindex(a->size);
-
- p = findblk(i,a);
-
- concatblk(a,p);
-
- if ((char *)p + p->size == (char *)a)
- {
- p->size += a->size;
- #ifdef M_DEBUG
- a->magic = 0;
- #endif
- }
- else
- addblk(i,a,p);
- }
-
- #ifdef M_DEBUG
- void __m_debug(void) /* dump free lists */
- {
- register blk *b;
- register int i;
-
- for (i = 0; i < NFL; i++)
- {
- printf("\nfl: %d ( >= %d )\n",i,__flmin[i] - BLKSIZ);
- b = __fl + i; do
- {
- b = b->next;
- printf("%7x: next: %7x [%7x] size: %x\n",b,b->next,
- (char *)b + b->size,b->size - BLKSIZ);
- assert(addr(b));
- assert(b->magic == MAGIC);
- }
- while (b->next > b);
- }
- putchar('\n');
- }
- #endif
-